import flet as ft
from typing import Optional, Dict
import threading
import asyncio
from utils.config import Config
from utils.task_manager import TaskManager
from downloaders.factory import DownloaderFactory

class VideoDownloaderApp:
    def __init__(self):
        self.config = Config()
        self.task_manager = TaskManager(self.config)
        self.current_video_info: Optional[Dict] = None
        self.current_url: str = ""
        self.download_thread: Optional[threading.Thread] = None
        self.is_downloading = False
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(self.loop)
        
    def create_home_page(self) -> ft.View:
        """创建主页面"""
        # 创建URL输入框
        self.url_input = ft.TextField(
            label="视频链接",
            hint_text="请输入视频链接",
            width=600,
            multiline=False,
            prefix_icon=ft.icons.LINK
        )
        
        # 创建解析按钮
        self.parse_button = ft.ElevatedButton(
            text="解析",
            icon=ft.icons.SEARCH,
            on_click=self.parse_url
        )
        
        # 创建视频信息卡片
        self.video_card = ft.Card(
            content=ft.Container(
                content=ft.Column([
                    ft.Text("视频信息", size=20, weight=ft.FontWeight.BOLD),
                    ft.Text("请先输入视频链接并解析", size=16)
                ]),
                padding=20
            ),
            visible=False
        )
        
        # 创建下载按钮
        self.download_button = ft.ElevatedButton(
            text="开始下载",
            icon=ft.icons.DOWNLOAD,
            on_click=self.start_download,
            disabled=True
        )
        
        # 创建打开文件夹按钮
        self.open_folder_button = ft.ElevatedButton(
            text="打开下载目录",
            icon=ft.icons.FOLDER_OPEN,
            on_click=self.open_download_folder
        )
        
        # 创建主页面布局
        return ft.View(
            "/",
            [
                ft.Container(
                    content=ft.Column([
                        ft.Text("视频下载器", size=30, weight=ft.FontWeight.BOLD),
                        ft.Row([
                            self.url_input,
                            self.parse_button
                        ], alignment=ft.MainAxisAlignment.CENTER),
                        self.video_card,
                        ft.Row([
                            self.download_button,
                            self.open_folder_button
                        ], alignment=ft.MainAxisAlignment.CENTER)
                    ]),
                    padding=20
                )
            ],
            horizontal_alignment=ft.CrossAxisAlignment.CENTER
        )
    
    def create_download_page(self) -> ft.View:
        """创建下载列表页面"""
        # 创建下载列表
        self.download_list = ft.ListView(
            expand=1,
            spacing=10,
            padding=20,
            height=400
        )
        
        # 更新下载列表
        self.update_download_list()
        
        return ft.View(
            "/downloads",
            [
                ft.Container(
                    content=ft.Column([
                        ft.Text("下载列表", size=30, weight=ft.FontWeight.BOLD),
                        self.download_list
                    ]),
                    padding=20
                )
            ]
        )
    
    def create_settings_page(self) -> ft.View:
        """创建设置页面"""
        # 创建下载目录输入框
        self.download_dir_input = ft.TextField(
            label="下载目录",
            value=self.config.download_dir,
            width=600,
            multiline=False,
            prefix_icon=ft.icons.FOLDER
        )
        
        # 创建保存按钮
        save_button = ft.ElevatedButton(
            text="保存设置",
            icon=ft.icons.SAVE,
            on_click=self.save_settings
        )
        
        return ft.View(
            "/settings",
            [
                ft.Container(
                    content=ft.Column([
                        ft.Text("设置", size=30, weight=ft.FontWeight.BOLD),
                        self.download_dir_input,
                        save_button
                    ]),
                    padding=20
                )
            ],
            horizontal_alignment=ft.CrossAxisAlignment.CENTER
        )
    
    def parse_url(self, e):
        """解析视频链接"""
        url = self.url_input.value.strip()
        if not url:
            self.show_error_dialog("错误", "请输入视频链接")
            return
        
        # 更新按钮状态
        self.parse_button.disabled = True
        self.parse_button.text = "解析中..."
        self.url_input.disabled = True
        
        try:
            # 获取下载器
            downloader = DownloaderFactory.get_downloader(url, self.config)
            if not downloader:
                raise Exception("不支持的视频链接")
            
            # 提取视频信息
            self.current_video_info = self.loop.run_until_complete(downloader.extract_video_info(url))
            self.current_url = url
            
            # 更新视频信息卡片
            self.update_video_card()
            
            # 启用下载按钮
            self.download_button.disabled = False
            
        except Exception as e:
            self.show_error_dialog("错误", str(e))
            self.current_video_info = None
            self.current_url = ""
            self.download_button.disabled = True
            
        finally:
            # 恢复按钮状态
            self.parse_button.disabled = False
            self.parse_button.text = "解析"
            self.url_input.disabled = False
    
    def update_video_card(self):
        """更新视频信息卡片"""
        if not self.current_video_info:
            return
        
        # 创建格式选择下拉框
        format_dropdown = ft.Dropdown(
            label="选择视频质量",
            width=400,
            options=[
                ft.dropdown.Option(
                    text=f"{f['format_note']} - {f['resolution']}",
                    key=f['format_id']
                )
                for f in self.current_video_info['formats']
            ]
        )
        
        # 更新视频卡片内容
        self.video_card.content = ft.Container(
            content=ft.Column([
                ft.Text("视频信息", size=20, weight=ft.FontWeight.BOLD),
                ft.Text(f"标题：{self.current_video_info['title']}", size=16),
                format_dropdown
            ]),
            padding=20
        )
        self.video_card.visible = True
    
    def start_download(self, e):
        """开始下载视频"""
        if not self.current_video_info or not self.current_url:
            self.show_error_dialog("错误", "请先解析视频")
            return
        
        # 获取选择的格式
        format_id = None
        for control in self.video_card.content.content.controls:
            if isinstance(control, ft.Dropdown):
                format_id = control.value
                break
        
        if not format_id:
            self.show_error_dialog("错误", "请选择视频质量")
            return
        
        # 创建下载任务
        task_id = self.task_manager.create_task(
            url=self.current_url,
            format_id=format_id,
            title=self.current_video_info['title'],
            thumbnail=self.current_video_info['cover_url'],
            format_note=next(
                (f['format_note'] for f in self.current_video_info['formats'] 
                 if f['format_id'] == format_id),
                ""
            ),
            resolution=next(
                (f['resolution'] for f in self.current_video_info['formats'] 
                 if f['format_id'] == format_id),
                ""
            ),
            ext="mp4"
        )
        
        # 开始下载
        self.download_thread = threading.Thread(
            target=self.process_download_queue,
            daemon=True
        )
        self.download_thread.start()
        
        # 显示成功消息
        self.show_snack_bar("下载任务已添加到队列")
    
    def process_download_queue(self):
        """处理下载队列"""
        while self.task_manager.download_queue:
            task_id = self.task_manager.download_queue[0]
            task = self.task_manager.get_task(task_id)
            
            if not task:
                self.task_manager.download_queue.pop(0)
                continue
            
            try:
                # 获取下载器
                downloader = DownloaderFactory.get_downloader(task['url'], self.config)
                if not downloader:
                    raise Exception("不支持的视频链接")
                
                # 更新任务状态
                self.task_manager.update_task_status(task_id, "downloading")
                
                # 开始下载
                success, message = self.loop.run_until_complete(downloader.download_video(
                    task['url'],
                    task['format_id'],
                    lambda progress: self.task_manager.update_task_progress(task_id, progress)
                ))
                
                if success:
                    self.task_manager.update_task_status(task_id, "completed")
                else:
                    self.task_manager.update_task_status(task_id, "failed", message)
                
            except Exception as e:
                self.task_manager.update_task_status(task_id, "failed", str(e))
            
            finally:
                # 从队列中移除任务
                self.task_manager.download_queue.pop(0)
                # 更新下载列表
                self.update_download_list()
    
    def update_download_list(self):
        """更新下载列表"""
        self.download_list.controls.clear()
        
        for task in self.task_manager.get_all_tasks():
            # 创建任务卡片
            card = ft.Card(
                content=ft.Container(
                    content=ft.Column([
                        ft.Text(task['title'], size=16, weight=ft.FontWeight.BOLD),
                        ft.Text(f"状态：{task['status']}", size=14),
                        ft.Text(f"进度：{task['progress']:.1f}%", size=14),
                        ft.Row([
                            ft.ElevatedButton(
                                text="取消",
                                on_click=lambda t=task: self.cancel_task(t['id'])
                            ) if task['status'] in ['queued', 'downloading'] else ft.Container(),
                            ft.ElevatedButton(
                                text="暂停",
                                on_click=lambda t=task: self.pause_task(t['id'])
                            ) if task['status'] in ['queued', 'downloading'] else ft.Container(),
                            ft.ElevatedButton(
                                text="恢复",
                                on_click=lambda t=task: self.resume_task(t['id'])
                            ) if task['status'] == 'paused' else ft.Container()
                        ])
                    ]),
                    padding=10
                )
            )
            self.download_list.controls.append(card)
    
    def cancel_task(self, task_id: int):
        """取消任务"""
        self.task_manager.cancel_task(task_id)
        self.update_download_list()
    
    def pause_task(self, task_id: int):
        """暂停任务"""
        self.task_manager.pause_task(task_id)
        self.update_download_list()
    
    def resume_task(self, task_id: int):
        """恢复任务"""
        self.task_manager.resume_task(task_id)
        self.update_download_list()
    
    def open_download_folder(self, e):
        """打开下载目录"""
        import os
        import platform
        
        if platform.system() == 'Windows':
            os.startfile(self.config.download_dir)
        elif platform.system() == 'Darwin':  # macOS
            os.system(f'open "{self.config.download_dir}"')
        else:  # Linux
            os.system(f'xdg-open "{self.config.download_dir}"')
    
    def save_settings(self, e):
        """保存设置"""
        self.config.download_dir = self.download_dir_input.value
        self.config.save_settings()
        self.show_snack_bar("设置已保存")
    
    def show_error_dialog(self, title: str, message: str):
        """显示错误对话框"""
        def close_dlg(e):
            dlg.open = False
            self.page.update()
        
        dlg = ft.AlertDialog(
            title=ft.Text(title),
            content=ft.Text(message),
            actions=[
                ft.TextButton("确定", on_click=close_dlg),
            ],
            actions_alignment=ft.MainAxisAlignment.END,
        )
        
        self.page.dialog = dlg
        dlg.open = True
        self.page.update()
    
    def show_snack_bar(self, message: str):
        """显示提示消息"""
        self.page.show_snack_bar(
            ft.SnackBar(content=ft.Text(message))
        ) 